package com.zzyl.nursing.service.impl;

import java.io.IOException;
import java.time.LocalDateTime;
import java.util.List;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.zzyl.common.exception.base.BaseException;
import com.zzyl.common.utils.DateUtils;
import com.zzyl.common.utils.IDCardUtils;
import com.zzyl.common.utils.StringUtils;
import com.zzyl.common.utils.ai.AIModelInvoker;
import com.zzyl.common.utils.pdfutils.PDFUtil;
import com.zzyl.nursing.dto.HealthAssessmentDTO;
import com.zzyl.nursing.vo.health.HealthReportVo;
import com.zzyl.oss.AliyunOSSOperator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import com.zzyl.nursing.mapper.HealthAssessmentMapper;
import com.zzyl.nursing.domain.HealthAssessment;
import com.zzyl.nursing.service.IHealthAssessmentService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.web.multipart.MultipartFile;

import java.util.Arrays;

import static com.zzyl.common.constant.CacheConstants.NURSING_TIJIAN_KEY;
import static com.zzyl.common.constant.CacheConstants.PROMPT;

/**
 * 健康评估Service业务层处理
 *
 * @author ruoyi
 * @date 2025-02-22
 */
@Service
public class HealthAssessmentServiceImpl extends ServiceImpl<HealthAssessmentMapper, HealthAssessment> implements IHealthAssessmentService {
    @Autowired
    private HealthAssessmentMapper healthAssessmentMapper;


    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private AIModelInvoker aiModelInvoker;

    @Autowired
    private AliyunOSSOperator aliyunOSSOperator;


    /**
     * 查询健康评估
     *
     * @param id 健康评估主键
     * @return 健康评估
     */
    @Override
    public HealthAssessment selectHealthAssessmentById(Long id) {
        return getById(id);
    }

    /**
     * 查询健康评估列表
     *
     * @param healthAssessment 健康评估
     * @return 健康评估
     */
    @Override
    public List<HealthAssessment> selectHealthAssessmentList(HealthAssessment healthAssessment) {
        return healthAssessmentMapper.selectHealthAssessmentList(healthAssessment);
    }

    /**
     * 修改健康评估
     *
     * @param healthAssessment 健康评估
     * @return 结果
     */
    @Override
    public int updateHealthAssessment(HealthAssessment healthAssessment) {
        return updateById(healthAssessment) ? 1 : 0;
    }

    /**
     * 批量删除健康评估
     *
     * @param ids 需要删除的健康评估主键
     * @return 结果
     */
    @Override
    public int deleteHealthAssessmentByIds(Long[] ids) {
        return removeByIds(Arrays.asList(ids)) ? 1 : 0;
    }

    /**
     * 删除健康评估信息
     *
     * @param id 健康评估主键
     * @return 结果
     */
    @Override
    public int deleteHealthAssessmentById(Long id) {
        return removeById(id) ? 1 : 0;
    }

    @Override
    public String upload(MultipartFile file, String idCardNo) throws Exception {
        // 上传文件
        String URL = aliyunOSSOperator.upload(file.getBytes(), file.getOriginalFilename());
        //读取PDF文件
        String tiJian = PDFUtil.pdfToString(file.getInputStream());

        //判断PDF是否为空 不为空则存储到Redis当中
        if (!ObjectUtil.isEmpty(tiJian)) {
            redisTemplate.opsForHash().put(NURSING_TIJIAN_KEY, idCardNo, tiJian);
        }
        return URL;
    }

    /**
     * 新增健康评估
     *
     * @param healthAssessmentdto 健康评估
     * @return id
     */
    @Override
    public Long add(HealthAssessmentDTO healthAssessmentdto) {
        String format = getString(healthAssessmentdto);

        //把format交给千帆模型进行处理数据
        String result = aiModelInvoker.qianfanInvoker(format);
        //把JSON数据转成对象
        HealthReportVo bean = JSONUtil.toBean(result, HealthReportVo.class);

        //创建HealthReport对象 开始如数据库表
        HealthAssessment healthAssessment = new HealthAssessment();
        healthAssessment.setElderName(healthAssessmentdto.getElderName());  //老人姓名（表）
        healthAssessment.setIdCard(healthAssessmentdto.getIdCard());      //老人身份证（表）

        //根据老人身份证提取出生日期
        LocalDateTime birthDateByIdCard = IDCardUtils.getBirthDateByIdCard(healthAssessmentdto.getIdCard());
        healthAssessment.setBirthDate(birthDateByIdCard);                   //老人生日（根据身份证提取）

        //根据老人身份证提取年龄
        int ageByIdCard = IDCardUtils.getAgeByIdCard(healthAssessmentdto.getIdCard());
        healthAssessment.setAge(ageByIdCard);                              //老人年龄（根据身份证提取）

        //根据老人身份证提取性别
        int genderFromIdCard = IDCardUtils.getGenderFromIdCard(healthAssessmentdto.getIdCard());
        healthAssessment.setGender(genderFromIdCard);

        //体检机构赋值
        healthAssessment.setPhysicalExamInstitution(healthAssessmentdto.getPhysicalExamInstitution());  //体检机构（表）

        //总检日期
        healthAssessment.setTotalCheckDate(bean.getTotalCheckDate());       //总检日期（Ai生成）

        //体检报告URL赋值
        healthAssessment.setPhysicalReportUrl(healthAssessmentdto.getPhysicalReportUrl());

        //体检评分
        double healthIndex = bean.getHealthAssessment().getHealthIndex();
        healthAssessment.setHealthScore(String.valueOf(healthIndex));       //体检评分（Ai生成）

        //体检风险等级
        extracted(healthIndex, healthAssessment);                           //体检风险等级（Ai生成）

        //建议入住
        healthAssessment.setSuggestionForAdmission(healthIndex > 60 ? 0 : 1);   //建议入住（Ai生成）

        //推荐护理等级
        extracted1(healthIndex, healthAssessment);                              //推荐护理等级（Ai生成）

        //入住情况
        healthAssessment.setAdmissionStatus(1);                                //入住情况（人为）

        //评估时间
        healthAssessment.setAssessmentTime(LocalDateTime.now());            //评估时间（人为）

        //报告总结
        healthAssessment.setReportSummary(bean.getSummarize());             //报告总结（Ai生成）

        //疾病风险
        healthAssessment.setDiseaseRisk(JSONUtil.toJsonStr(bean.getRiskDistribution()));    //疾病风险（Ai生成）

        //异常分析(转换成JSON)
        healthAssessment.setAbnormalAnalysis(JSONUtil.toJsonStr(bean.getAbnormalData()));   //异常分析（Ai生成）

        //体检系统分值
        healthAssessment.setSystemScore(JSONUtil.toJsonStr(bean.getSystemScore()));         //体检系统分值（Ai生成）

        save(healthAssessment);
        return healthAssessment.getId();
    }

    private static void extracted1(double healthIndex, HealthAssessment healthAssessment) {
        //推荐护理等级
        if (healthIndex >= 90) {
            healthAssessment.setNursingLevelName("三级护理");
        } else if (healthIndex >= 70) {
            healthAssessment.setNursingLevelName("二级护理");
        } else if (healthIndex >= 50) {
            healthAssessment.setNursingLevelName("一级护理");
        } else {
            healthAssessment.setNursingLevelName("不建议入住");
        }
    }

    private static void extracted(double healthIndex, HealthAssessment healthAssessment) {
        if (healthIndex >= 80) {
            healthAssessment.setRiskLevel("健康");
        } else if (healthIndex >= 60) {
            healthAssessment.setRiskLevel("提示");
        } else if (healthIndex >= 50) {
            healthAssessment.setRiskLevel("风险");
        } else if (healthIndex >= 30) {
            healthAssessment.setRiskLevel("危险");
        } else if (healthIndex >= 10) {
            healthAssessment.setRiskLevel("严重危险");
        }
    }

    /**
     * 组装prompt模版
     *
     * @param healthAssessmentdto 表中数据
     * @return AI生成的JSON
     */
    private String getString(HealthAssessmentDTO healthAssessmentdto) {
        //根据身份证在Redis中获取体检报告
        String tjbg = (String) redisTemplate.opsForHash().get(NURSING_TIJIAN_KEY, healthAssessmentdto.getIdCard());
        // 判断Redis是否为空
        if (StringUtils.isEmpty(tjbg)) {
            throw new BaseException("体检报告有误，请重新上传");
        }
        //删除Redis数据
        redisTemplate.opsForHash().delete(NURSING_TIJIAN_KEY, healthAssessmentdto.getIdCard());

        //把体检报告和默认进行组装
        String format = StringUtils.format(PROMPT, tjbg);
        return format;
    }
}
